package com.jxtc.enterprise.hr.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jxtc.enterprise.admin.vo.AdminBillLogVO;
import com.jxtc.enterprise.common.constants.AuditResultEnum;
import com.jxtc.enterprise.common.constants.CompanySettlementStatusEnum;
import com.jxtc.enterprise.common.entity.CompanySettlement;
import com.jxtc.enterprise.common.exception.ModifyFailureException;
import com.jxtc.enterprise.common.mapper.CompanySettlementMapper;
import com.jxtc.enterprise.common.utils.CurrencyUtil;
import com.jxtc.enterprise.common.utils.Result;
import com.jxtc.enterprise.common.utils.ResultGenerator;
import com.jxtc.enterprise.common.vo.PaginationResponseVO;
import com.jxtc.enterprise.hr.dto.HrSubmitCompanySettlementDTO;
import com.jxtc.enterprise.hr.dto.PageCompanySettlementDTO;
import com.jxtc.enterprise.hr.vo.HrCompanySettlementDetailVO;
import com.jxtc.enterprise.hr.vo.HrCompanySettlementPageVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/jxtc/enterprise/hr/settle")
@RequiredArgsConstructor
@Slf4j
public class HrCompanySettlementController {

    private final CompanySettlementMapper companySettlementMapper;

    @ApiResponse(responseCode = "200", description = "code 为 200 时，data 字段为结算状态字典列表")
    @Operation(summary = "23.1 获取结算状态下拉列表", tags = "23. HR 端订单结算", operationId = "23.1")
    @GetMapping("/queryStatusList")
    public Result<?> queryStatusList() {
        // 将结算状态枚举类中的 name - value 转换成列表的形式
        List<Map<String, Object>> settlementStatusList = CompanySettlementStatusEnum.toList();
        return ResultGenerator.genSuccessResult(settlementStatusList);
    }

    @ApiResponse(responseCode = "200", description = "code 为 200 时，data 字段为包含订单结算列表的分页信息")
    @Operation(summary = "23.2 分页查询订单结算列表", tags = "23. HR 端订单结算", operationId = "23.2")
    @PostMapping("/queryCompanySettlementList")
    public Result<PaginationResponseVO<HrCompanySettlementPageVO>> queryCompanySettlementList(@Valid @RequestBody PageCompanySettlementDTO dto) {
        log.info("/hr/queryCompanySettlementList, companyId: {}, startDate: {}, endDate: {}, status: {}, pageNo: {}, pageSize: {}",
                dto.getCompanyId(), dto.getStartDate(), dto.getEndDate(), dto.getStatus(), dto.getPageNo(), dto.getPageSize());

        Page<CompanySettlement> page = new Page<>(dto.getPageNo(), dto.getPageSize());

        LambdaQueryWrapper<CompanySettlement> queryWrapper = new LambdaQueryWrapper<CompanySettlement>()
                .eq(CompanySettlement::getDelFlag, false)
                .eq(CompanySettlement::getCompanyId, dto.getCompanyId())
                .orderByDesc(CompanySettlement::getMonth, CompanySettlement::getEndDate, CompanySettlement::getStartDate);

        // 如果开始时间不空，筛选结算开始时间 >= startDate 的记录
        if (dto.getStartDate() != null && !dto.getStartDate().isEmpty()) {
            queryWrapper.ge(CompanySettlement::getStartDate, dto.getStartDate());
        }

        // 如果结束时间不空，筛选结算结束时间 <= endDate 的记录
        if (dto.getEndDate() != null && !dto.getEndDate().isEmpty()) {
            queryWrapper.le(CompanySettlement::getEndDate, dto.getEndDate());
        }

        // 如果结算状态不空且不为 0，筛选结算状态 = status 的记录
        if (dto.getStatus() != null && dto.getStatus() != 0) {
            queryWrapper.eq(CompanySettlement::getStatus, dto.getStatus());
        }

        Page<CompanySettlement> result = companySettlementMapper.selectPage(page, queryWrapper);
        List<HrCompanySettlementPageVO> records = result.getRecords().stream()
                .map(this::buildCompanySettlementPageVO)
                .collect(Collectors.toList());

        PaginationResponseVO<HrCompanySettlementPageVO> vo = new PaginationResponseVO<>(result.getTotal(), result.getCurrent(), records);
        log.info("/queryCompanySettlementList, {}", vo);

        return ResultGenerator.genSuccessResult(vo);
    }

    private HrCompanySettlementPageVO buildCompanySettlementPageVO(CompanySettlement companySettlement) {
        HrCompanySettlementPageVO vo = new HrCompanySettlementPageVO();
        vo.setId(companySettlement.getId());
        vo.setMonth(companySettlement.getMonth());
        vo.setStartDate(companySettlement.getStartDate());
        vo.setEndDate(companySettlement.getEndDate());

        // 获取提示日期
        Integer noteDay = companySettlement.getNoteDay() == null ? 0 : companySettlement.getNoteDay();
        vo.setNoteDay(noteDay);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate targetDate = LocalDate.parse(companySettlement.getEndDate(), formatter);
        LocalDate currentDate = LocalDate.now();
        // 计算当前日期到目标日期还剩多少天
        long remainingDays = ChronoUnit.DAYS.between(currentDate, targetDate);
        vo.setRemainingDays(remainingDays);

        Integer statusValue = companySettlement.getStatus();
        vo.setStatusValue(statusValue);
        vo.setStatusName(CompanySettlementStatusEnum.getNameByValue(statusValue));
        vo.setBillUrl(companySettlement.getBillUrl());
        return vo;
    }


    @ApiResponse(responseCode = "200", description = "code 为 200 时，data 字段为结算详情信息；code 为 400 时，message 字段给出错误提示信息")
    @Parameter(name = "settleId", description = "公司结算记录 ID", example = "26e7c8b17867fa08584f92e1638b8eba")
    @Operation(summary = "23.3 查询结算详情", tags = "23. HR 端订单结算", operationId = "23.3")
    @GetMapping("/queryCompanySettlementDetails")
    public Result<HrCompanySettlementDetailVO> queryCompanySettlementDetails(@RequestParam String settleId) {
        log.info("/hr/queryCompanySettlementDetails, settleId: {}", settleId);

        LambdaQueryWrapper<CompanySettlement> queryWrapper = new LambdaQueryWrapper<CompanySettlement>()
                .eq(CompanySettlement::getId, settleId)
                .eq(CompanySettlement::getDelFlag, false);

        CompanySettlement companySettlement = companySettlementMapper.selectOne(queryWrapper);

        if (companySettlement == null) {
            throw new IllegalArgumentException("ID 为 " + settleId + " 的结算记录不存在，请联系管理员排查");
        }

        // 如果当前查询的结算记录处于 "未结算" 状态，提示前端 "未结算的记录无法查看详情"
        // if (companySettlement.getStatus() == CompanySettlementStatusEnum.NOT_SETTLED.getValue()) {
        //    throw new IllegalArgumentException("未结算的记录无法查看详情");
        // }

        HrCompanySettlementDetailVO vo = new HrCompanySettlementDetailVO();
        vo.setSettleId(settleId);

        String billPeriod = String.format("%s ~ %s", companySettlement.getStartDate(), companySettlement.getEndDate());
        vo.setBillPeriod(billPeriod);
        vo.setTotalOrderCount(companySettlement.getTotalOrderCount());

        String orderMoneyInYuan = CurrencyUtil.fenToYuan(companySettlement.getOrderMoney());
        vo.setOrderMoney(orderMoneyInYuan);

        String additionalMoneyInYuan = CurrencyUtil.fenToYuan(companySettlement.getAdditionalMoney());
        vo.setAdditionalMoney(additionalMoneyInYuan);

        String deductionMoneyInYuan = CurrencyUtil.fenToYuan(companySettlement.getDeductionMoney());
        vo.setDeductionMoney(deductionMoneyInYuan);

        int billTotalMoneyInFen = companySettlement.getOrderMoney() + companySettlement.getAdditionalMoney() - companySettlement.getDeductionMoney();
        String billTotalMoneyInYuan = CurrencyUtil.fenToYuan(billTotalMoneyInFen);
        vo.setBillTotalMoney(billTotalMoneyInYuan);

        List<String> invoiceImages = JSONUtil.toList(companySettlement.getInvoiceImages(), String.class);
        vo.setInvoiceImages(invoiceImages);

        List<String> transferImages = JSONUtil.toList(companySettlement.getTransferImages(), String.class);
        vo.setTransferImages(transferImages);

        List<AdminBillLogVO> billLogs = JSONUtil.toList(companySettlement.getBillLog(), AdminBillLogVO.class);
        vo.setBillLogs(billLogs);

        Integer statusValue = companySettlement.getStatus();
        vo.setStatusName(CompanySettlementStatusEnum.getNameByValue(statusValue));
        vo.setStatusValue(statusValue);

        log.info("/hr/queryCompanySettlementDetails, 响应结果: {}", vo);

        return ResultGenerator.genSuccessResult(vo);
    }


    @ApiResponse(responseCode = "200", description = "code 为 200 时，表示提交结算订单成功，data 字段为空；code 为 400 时，message 字段给出错误提示信息")
    @Operation(summary = "23.4 提交结算订单", tags = "23. HR 端订单结算", operationId = "23.4")
    @PostMapping("/submitCompanySettlement")
    public Result<Void> submitCompanySettlement(@Valid @RequestBody HrSubmitCompanySettlementDTO dto) {
        log.info("/hr/submitCompanySettlement, settleId: {}, auditResult: {}, comment: {}",
                dto.getSettleId(), dto.getAuditResult(), dto.getComment());

        CompanySettlement savedCompanySettlement = companySettlementMapper.selectById(dto.getSettleId());
        if (savedCompanySettlement == null) {
            throw new IllegalArgumentException("ID 为 " + dto.getSettleId() + " 的结算记录不存在，请联系管理员排查");
        }

        CompanySettlement companySettlement = new CompanySettlement();
        companySettlement.setId(savedCompanySettlement.getId());


        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 默认 HR 会驳回，并设置结算状态未 "待平台复核"
        String comment = "HR 驳回账单";
        companySettlement.setStatus(CompanySettlementStatusEnum.PENDING_PLATFORM_CONFIRMATION.getValue());

        // 如果 HR 同意结算，设置结算状态未 "待结算"
        if (AuditResultEnum.AGREE.getName().equals(dto.getAuditResult())) {
            comment = "HR 同意账单";
            // 将结算状态设置为 "待结算"
            companySettlement.setStatus(CompanySettlementStatusEnum.PENDING_SETTLEMENT.getValue());
        }

        // 如果填写了备注信息，将备注信息拼接在结算流程日志中
        if (dto.getComment() != null && !dto.getComment().isEmpty()) {
            comment += "，备注：" + dto.getComment();
        }

        List<AdminBillLogVO> billLogs = JSONUtil.toList(savedCompanySettlement.getBillLog(), AdminBillLogVO.class);
        AdminBillLogVO adminBillLogVO = new AdminBillLogVO(now.format(formatter), comment);
        billLogs.add(adminBillLogVO);

        String billLogStr = JSONUtil.toJsonStr(billLogs);
        companySettlement.setBillLog(billLogStr);

        int updateCount = companySettlementMapper.updateById(companySettlement);
        log.info("/hr/submitCompanySettlement, update count: {}", updateCount);

        if (updateCount <= 0) {
            throw new ModifyFailureException("提交结算订单失败，请联系管理员排查");
        }

        return ResultGenerator.genSuccessResult();
    }

}
